<template>
  <view>
    <pay-popup-header
      :priceVirtualRate="priceVirtualRate"
      :height="headerHeight"
      :virtualcoinPrice="virtualcoinPrice"
      :paidTotal="dramaWaitUnlockNum"
      :allTotal="dramaEpisodeNum"
      :userVirtualCoins="userVirtualCoins"
      agreementName="充值服务协议"
      @agreementClick="openRechargeAgreementPopup"
      @hideClick="hideClick"
    ></pay-popup-header>
    <view style="width: 100%" :style="{ height: `${scrollViewHeight}px` }">
      <mxp-refresh-scroll-view
        ref="mxpRefreshScrollViewRef"
        :height="`${scrollViewHeight}px`"
        :autoLaad="false"
        :style="{ height: `${scrollViewHeight}px`, width: '750rpx' }"
        :queryData="queryData"
      >
        <template v-if="payList.length > 0">
          <view class="pay-list">
            <pay-select-item
              v-for="(item, index) in payList"
              :key="index"
              style="width: 100%"
              :active="currIndex === index"
              :productName="item.productName || ''"
              :productPrice="item.productPrice || ''"
              :productType="item.productType"
              :marketingDesc="item.marketingDesc || ''"
              :recommendTags="item.recommendTags || ''"
              unit="元"
              @myClick="changeMoney(index)"
            ></pay-select-item>
          </view>
          <view class="hint-box">
            <text class="title">温馨提示：</text>
            <text class="hint">1. 虚拟物品付费后不支持退款</text>
            <text class="hint">2. 付费解锁后可永久观看</text>
            <text class="hint">3. K币充值后不可反向兑换为人民币等其他法定货币</text>
            <text class="hint">4. 会员有效期内可免费观看无需付费解锁，会员过期后无法观看(已付费解锁剧集除外)</text>
            <text class="hint">5. 在播剧目{{ dramaOnlineNum }}部</text>
            <text class="hint">6. 未满18岁的未成年,应在监护人同意或授权下充值</text>
            <view class="agreement-box">
              <text class="hint">7. 充值代表同意</text>
              <text class="hint" :style="{ color: '#223aec' }" @click="openRechargeAgreementPopup">《充值服务协议》</text>
              <text class="hint">和</text>
              <text class="hint" :style="{ color: '#223aec' }" @click="openMembershipAgreementPopup">《VIP服务协议》</text>
            </view>
            <!-- 微信不用加下面的占位 -->
            <!-- <view v-if="isAutoPay" :style="{ height: `${safeAreaInsetBottom}px` }"></view> -->
          </view>
        </template>
      </mxp-refresh-scroll-view>
    </view>
    <!-- 支付 -->
    <view v-if="!isAutoPay" class="bottom-box" :style="{ height: `${bottomHeight}px` }">
      <mxp-button text="余额解锁" fontSize="13px" width="200rpx" height="32px" @click="balanceUnlock"></mxp-button>
      <mxp-radio
        :checked="isAutoPay"
        :cusStyle="{ pointerEvents: 'auto' }"
        :loading="autoPayLoading"
        labelSize="12px"
        label="自动使用余额解锁"
        iconSize="18px"
        :labelColor="defThemeColor.text3"
        :beforeChange="switchBeforeChange"
      ></mxp-radio>
    </view>
    <!-- 微信不用加下面的占位 -->
    <!-- <view v-if="!isAutoPay" key="view-2" :style="{ height: `${safeAreaInsetBottom}px` }"></view> -->
    <!-- VIP服务协议 -->
    <membership-agreement-popup ref="membershipAgreementPopupRef" :pageHeight="`${popupHeight}px`" :height="popupHeight - 50"></membership-agreement-popup>
    <!-- 充值服务协议 -->
    <recharge-agreement-popup ref="rechargeAgreementPopupRef" :pageHeight="`${popupHeight}px`" :height="popupHeight - 50"></recharge-agreement-popup>
  </view>
</template>

<script setup lang="ts">
  import { computed, onMounted, ref, watch } from 'vue';
  import PayPopupHeader from '@/components/pay/pay-popup-header/pay-popup-header.vue';
  import PaySelectItem from '@/components/pay/pay-select-item/pay-select-item.vue';
  import MxpRadio from '@/mxp-ui/mxp-radio/mxp-radio.vue';
  import MembershipAgreementPopup from '@/components/page/membership-agreement/membership-agreement-popup.vue';
  import RechargeAgreementPopup from '@/components/page/recharge-agreement/recharge-agreement-popup.vue';
  import MxpButton from '@/mxp-ui/mxp-button/mxp-button.vue';
  import {
    type Product,
    addAdRecordAxios,
    createWechatAdvertOrderAxios,
    createWechatDramaOrderAxios,
    getDramaCommodityInfoAxios,
    queryDramaWechatPayResultAxios,
    wechatCreateBalanceOrderAxios,
  } from '@/api/pay';
  import { wxOrderPay, wxOrderVirtualPay } from '@/utils/payUtil';
  import { useAppStore } from '@/pinia/app';
  import { sleep } from '@/mxp-ui/mxp-tool/utils/rest';
  import { autoLogin, updateUserInfo } from '@/utils/page/user';
  import mxpGetSysInfoStore from '@/mxp-ui/mxp-tool/store/mxp-store-sys-info';
  import { amendAutoPayAxios } from '@/api/account';
  import { defThemeColor } from '@/mxp-ui/mxp-tool/theme/theme';
  import MxpRefreshScrollView, { type Ins } from '@/mxp-ui/mxp-refresh-scroll-view/mxp-refresh-scroll-view.vue';
  import { eventTrackingPayTemplateAxios } from '@/api/drama';
  import { userActionLog } from '@/api/datapoint';

  defineOptions({
    name: 'charge-dialog',
  });

  /** 广告解锁：0-不支持；1-支持； */
  const advertUnlock = ref<0 | 1>(0);

  const plugin = requirePlugin('playlet-plugin');
  const showMescroll = ref(false);
  const showMescrollTimeout = ref<NodeJS.Timeout | undefined>(undefined);
  const sys = mxpGetSysInfoStore().getSysInfo();
  /** 上线剧目数量 */
  const dramaOnlineNum = ref(1);
  /** 待解锁剧集数量 */
  const dramaWaitUnlockNum = ref(0);
  const payList = ref<Product[]>([]);
  const loading = ref(false);
  const safeAreaInsetBottom = computed(() => sys.value.safeAreaInsets?.bottom || 0);
  const mxpRefreshScrollViewRef = ref<InstanceType<typeof MxpRefreshScrollView>>();
  /** 是否自动解锁 */
  const isPay = ref(false);
  const appStore = useAppStore();
  const queryDataLoading = ref(false);
  const membershipAgreementPopupRef = ref<InstanceType<typeof MembershipAgreementPopup> | null>(null);
  const rechargeAgreementPopupRef = ref<InstanceType<typeof RechargeAgreementPopup> | null>(null);
  const dramaEpisodeNum = ref(0);
  /** 是否自动解锁 */
  const isAutoPay = computed(() => appStore.userInfo?.isAutoPay === 1);
  /** 单集解锁价格 */
  const virtualcoinPrice = ref<number | string>('--');
  /** 用户余额 */
  const userVirtualCoins = computed(() => appStore.userInfo?.virtualCoins);

  const scrollViewHeight = computed(() => 3 * 100 + 2 * 15 + 40 + (isAutoPay.value ? 40 : 0));
  const headerHeight = 150;
  const bottomHeight = computed(() => (isAutoPay.value ? 0 : 40));
  const popupHeight = computed(
    () => scrollViewHeight.value + headerHeight + bottomHeight.value + (!isAutoPay.value ? safeAreaInsetBottom.value : 0) + safeAreaInsetBottom.value
  );

  const autoPayLoading = ref(false);

  const defaultIndex = ref(0);
  const currIndex = ref(0);
  const priceVirtualRate = ref(100);

  const devicePlatform = computed(() => (sys.value.platform === 'devtools' ? sys.value.osName : sys.value.platform));
  onMounted(() => {
    const managerInstance = getPlayerManager();
    /** 充值弹窗打开事件 */
    managerInstance.onShowChargeDialog(() => {
      currIndex.value = defaultIndex.value;
      const { dramaId, serialNo } = managerInstance!.getInfo();
      eventTrackingPayTemplateAxios({
        referralLinkId: appStore.launchQuery?.referralLinkId,
        episodeSeq: serialNo,
        playletId: dramaId,
      });
      mxpRefreshScrollViewRef.value?.initLoadRefresh();
      showMescrollTimeout.value || clearTimeout(showMescrollTimeout.value);
      showMescrollTimeout.value = setTimeout(() => {
        showMescroll.value = true;
      }, 300);
    });

    /** 充值弹窗关闭事件监听 */
    managerInstance.onHideChargeDialog(() => {
      rechargeAgreementPopupRef.value?.hide();
      membershipAgreementPopupRef.value?.hide();
      showMescrollTimeout.value || clearTimeout(showMescrollTimeout.value);
      showMescrollTimeout.value = setTimeout(() => {
        showMescroll.value = false;
      }, 300);
    });

    /** 关闭广告解锁视频事件 */
    managerInstance.onCustomEvent('adClose', async (data: { isEnded: boolean }) => {
      if (data.isEnded) {
        const { dramaId, serialNo } = managerInstance!.getInfo();
        let params = {
          thirdDramaId: dramaId!,
          clickId: appStore.launchQuery?.clickid,
          episodeSeq: Number(serialNo || 1),
          referralLinkId: appStore.launchQuery?.referralLinkId,
          promotionId: appStore.launchQuery?.promotionid,
          launchQueryPramas: appStore.newLaunchQuery || {},
        };
        try {
          uni.showLoading({ mask: true, title: '解锁中...' });
          const recordRes = await addAdRecordAxios(params);
          const param = { advertToken: recordRes.data.advertToken, thirdDramaId: dramaId, episodeSeq: serialNo! };
          const unlockOrderRes = await createWechatAdvertOrderAxios(param);
          managerInstance?.isCanPlay({ data: unlockOrderRes.data.encryptedData!, serialNo: Number(serialNo || 1), useLastStatus: false });
          uni.hideLoading();
          hide();
        } catch (error) {
          uni.showToast({ title: error.msg || '广告解锁失败,BD0007', icon: 'none', position: 'bottom' });
          uni.hideLoading();
          userActionLog({
            userId: appStore.userInfo?.userId,
            data: JSON.stringify(params),
            eventType: 'WX_ADCLOSE',
            msg: JSON.stringify(error),
          });
        }
      } else {
        const manager = getPlayerManager();
        appStore.updateWxAdPopupParam({ type: 2 });
        manager?.updateOpenArea({ showLeft: true });
      }
    });
  });

  watch(
    () => popupHeight.value,
    (val) => {
      getPlayerManager().updateChargeDialogHeight({
        height: val,
      });
    }
  );

  /** 得到短剧播放器实例 */
  function getPlayerManager() {
    return plugin.PlayletManager.getPageManager(appStore.wxPlayletCharge.playerId || '');
  }

  /** 查询支付状态以及支付后的短剧 */
  async function queryPayOrder(outTradeNo: string) {
    await sleep(1000); // 延迟两秒查询
    const mp = getPlayerManager();
    const { serialNo, dramaId } = mp!.getInfo();
    try {
      const queryRes = await queryDramaWechatPayResultAxios({ outTradeNo, thirdDramaId: dramaId });
      appStore.updateVirtualCoins(queryRes.data.virtualCoins);
      userActionLog({
        userId: appStore.userInfo?.userId,
        data: JSON.stringify({ outTradeNo, thirdDramaId: dramaId }),
        eventType: 'WX_QUERY_PAYORDER_OK',
        msg: JSON.stringify(queryRes.data),
      });
      if (queryRes.data.status === 1) {
        if (queryRes.data.productType === 1) {
          try {
            return await createDyBalanceOrder();
          } catch (error) {
            return Promise.reject({ code: error.code || -2001, msg: error.msg || '解锁失败' });
          }
        } else if (queryRes.data.productType === 2) {
          uni.showToast({ title: `开通会员成功`, icon: 'none', position: 'bottom' });
          mp?.isCanPlay({ data: queryRes.data.encryptedData!, serialNo: Number(serialNo), useLastStatus: false });
          return Promise.resolve(true);
        } else if (queryRes.data.productType === 4) {
          uni.showToast({ title: `您已解锁全集`, icon: 'none', position: 'bottom' });
          mp?.isCanPlay({ data: queryRes.data.encryptedData!, serialNo: Number(serialNo), useLastStatus: false });
          return Promise.resolve(true);
        } else {
          mp?.isCanPlay({ data: queryRes.data.encryptedData!, serialNo: Number(serialNo), useLastStatus: false });
          return Promise.resolve(true);
        }
      } else {
        userActionLog({
          userId: appStore.userInfo?.userId,
          data: JSON.stringify({ outTradeNo, thirdDramaId: dramaId }),
          eventType: 'WX_QUERY_PAYORDER',
          msg: JSON.stringify(queryRes),
        });
        return Promise.reject({ code: -1001, msg: '支付失败，BD10002' });
      }
    } catch (err) {
      userActionLog({
        userId: appStore.userInfo?.userId,
        data: JSON.stringify({ outTradeNo, thirdDramaId: dramaId }),
        eventType: 'WX_QUERY_PAYORDER_ERROR',
        msg: JSON.stringify(err),
      });
      return Promise.reject({ code: -1001, msg: '支付结果查询异常,如已成功支付,请重新进入该剧观看' });
    }
  }

  /** 余额解锁 */
  async function balanceUnlock() {
    try {
      await createDyBalanceOrder();
      hide();
    } catch (error) {
      uni.showToast({ title: error.msg, icon: 'none', position: 'bottom' });
    }
  }

  /** 余额解锁 */
  async function createDyBalanceOrder(): Promise<boolean> {
    const mp = getPlayerManager();
    const { serialNo, dramaId } = mp!.getInfo();
    const params = { thirdDramaId: dramaId, episodeSeq: serialNo, referralLinkId: appStore.launchQuery?.referralLinkId };
    try {
      const res = await wechatCreateBalanceOrderAxios(params);
      appStore.updateVirtualCoins(res.data.virtualCoins);
      if (res.data.unLockStatus === 1) {
        mp?.isCanPlay({ data: res.data.encryptedData!, serialNo: Number(serialNo), useLastStatus: false });
        uni.showToast({ title: res.data.unlockMsg, icon: 'none', position: 'bottom' });
        return Promise.resolve(true);
      } else {
        userActionLog({
          userId: appStore.userInfo?.userId,
          data: JSON.stringify(params),
          eventType: 'WX_CREATEDYBALANCEORDER',
          msg: JSON.stringify(res),
        });
        return Promise.reject({ code: -1002, msg: '余额不足或解锁失败，BD10002' });
      }
    } catch (error) {
      userActionLog({
        userId: appStore.userInfo?.userId,
        data: JSON.stringify(params),
        eventType: 'WX_CREATEDYBALANCEORDER',
        msg: JSON.stringify(error),
      });
      return Promise.reject({ code: -1002, msg: error.msg || '解锁失败' });
    }
  }

  /** 支付关闭 */
  function hideClick() {
    hide();
    if (advertUnlock.value === 1) {
      const manager = getPlayerManager();
      appStore.updateWxAdPopupParam({ type: 1 });
      manager?.updateOpenArea({ showLeft: true });
    }
  }

  /** 切换支付 */
  async function changeMoney(index: number) {
    if (!loading.value) {
      currIndex.value = index;
      if (isPay.value) {
        const { productType, productId } = payList.value[currIndex.value]!;
        try {
          loading.value = true;
          const { dramaId, serialNo, wxExportId, wxFinderId, wxPromotionId } = getPlayerManager().getInfo();
          const referralLinkId = appStore.launchQuery?.referralLinkId;

          const projectId = appStore.launchQuery?.projectid;
          const promotionId = appStore.launchQuery?.promotionid;
          uni.showLoading({ title: '加载中', mask: true });
          const order = await createWechatDramaOrderAxios({
            productType,
            productId,
            referralLinkId,
            clickId: appStore.launchQuery?.clickid,
            thirdDramaId: dramaId,
            episodeSeq: serialNo,
            projectId,
            promotionId,
            devicePlatform: devicePlatform.value,
            wxExportId: appStore.launchQuery?.wxExportId,
            wxFinderId: appStore.launchQuery?.wxFinderId,
            wxPromotionId: appStore.launchQuery?.wxPromotionId,
            channelId: appStore.launchQuery?.channelId,
            launchQueryPramas: appStore.newLaunchQuery || {},
          });

          if (devicePlatform.value === 'ios') {
            await wxOrderPay(order.data.paymentDTO!);
          } else {
            await wxOrderVirtualPay(order.data);
          }
          uni.showLoading({ title: '正在获取支付结果', mask: true });
          await queryPayOrder(order.data.outTradeNo || '');
          updateUserInfo(); // 更新个人资料
          loading.value = false;
          uni.hideLoading();
          hide();
        } catch (error) {
          uni.showToast({ title: error?.msg || '解锁失败,BD009', icon: 'none', position: 'bottom' });
          uni.hideLoading();
          loading.value = false;
        }
      } else {
        uni.showToast({ title: '由于平台限制,暂不支持支付', icon: 'none', position: 'bottom' });
      }
    }
  }

  /** 隐藏 */
  function hide() {
    getPlayerManager()?.hideChargeDialog();
  }
  /** 打开充值服务协议 */
  function openRechargeAgreementPopup() {
    rechargeAgreementPopupRef.value?.show();
  }
  /** 打开会员服务协议 */
  function openMembershipAgreementPopup() {
    membershipAgreementPopupRef.value?.show();
  }

  /** 修改自动解锁 */
  async function switchBeforeChange() {
    try {
      autoPayLoading.value = true;
      const res = await amendAutoPayAxios();
      appStore.updateIsAutoPay(res.data);
      autoPayLoading.value = false;
      return Promise.resolve(res.data === 1);
    } catch (error) {
      autoPayLoading.value = false;
      return Promise.reject(true);
    }
  }

  /** 加载中 */
  async function queryData(ins?: Ins | null) {
    try {
      if (!queryDataLoading.value && payList.value.length <= 0) {
        const { dramaId, wxExportId, wxFinderId, wxPromotionId } = getPlayerManager().getInfo();
        queryDataLoading.value = true;
        const thirdDramaId = dramaId;
        !appStore.loginState && (await autoLogin());
        const res = await getDramaCommodityInfoAxios({
          referralLinkId: appStore.launchQuery?.referralLinkId,
          thirdDramaId,
          devicePlatform: devicePlatform.value,
          wxFinderId: appStore.launchQuery?.wxFinderId,
          wxExportId: appStore.launchQuery?.wxExportId,
          wxPromotionId: appStore.launchQuery?.wxPromotionId,
        });
        priceVirtualRate.value = Number(appStore.baseDictInfo?.PRICE_VIRTUAL_RATE || '100');
        payList.value = res.data.productList || [];
        defaultIndex.value = res.data.selectIndex;
        currIndex.value = res.data.selectIndex;
        advertUnlock.value = res.data.advertUnlock === 1 ? 1 : 0;
        virtualcoinPrice.value = res.data.virtualCoin || 0;
        appStore.updateVirtualCoins(res.data.userVirtualCoins || appStore.userInfo?.virtualCoins || 0);
        isPay.value = res.data.pay;
        dramaEpisodeNum.value = res.data.dramaEpisodeNum || 0;
        dramaOnlineNum.value = res.data.dramaOnlineNum || 0;
        dramaWaitUnlockNum.value = res.data.dramaWaitUnlockNum || 0;
        queryDataLoading.value = false;
      }
      ins?.setSuccess();
    } catch (error) {
      queryDataLoading.value = false;
      payList.value = [];
      ins?.setEmpty('fail_load', error.msg || '获取数据失败，BD0001');
    }
  }
</script>

<style lang="scss" scoped>
  .pay-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap: 15px;
    justify-content: space-between;
    justify-items: center;
    padding: 15px;
  }

  .hint-box {
    display: flex;
    flex-direction: column;
    padding: 15px;
    padding-top: 0;

    .title {
      margin-bottom: 6px;
      font-size: 12px;
      font-weight: bold;
      color: #666666;
      word-break: break-all;
      word-wrap: break-word;
      white-space: normal !important;
    }

    .hint {
      margin-bottom: 6px;
      font-size: 12px;
      color: #999999;
      word-break: break-all;
      word-wrap: break-word;
      white-space: normal !important;
    }

    .agreement-box {
      display: flex;
      flex-direction: row;
      align-items: center;
    }
  }

  .bottom-box {
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 750rpx;
    padding: 0 15px;
  }
</style>
